<template>
  <div id="app">
    <el-container>
      <el-aside width="350px" class="aside">
        <HistoryPanel ref="historyPanel" @clickLink="changeURL" />
      </el-aside>
      <el-container>
        <el-header class="header">
          <div class="header-center">
            <el-form ref="urlForm" status-icon :show-message="false" @submit.native.prevent="onSubmit">
              <el-form-item :error="urlTypingError">
                <el-autocomplete
                  placeholder="输入 URL，回车确认"
                  v-model="urlTyping"
                  :fetch-suggestions="queryHistory"
                  size="small"
                  class="address-bar"
                />
              </el-form-item>
            </el-form>
          </div>
          <div class="header-right">
            <IntervalSetting v-model="interval" :loading="loading" @refresh="refresh" />
            <CustomizeConfig ref="customizeConfig" @change="config = $event" />
            <el-link href="https://gitee.com/run27017/swagger-doc-preview/issues" target="_blank">提交反馈</el-link>
          </div>
        </el-header>
        <el-main>
          <SwaggerPreview ref="swaggerPreview" :config="config" :url="url" :interval="interval" @loading="loading = true" @loaded="loading = false" v-if="url" />
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import HistoryPanel from './HistoryPanel'
import CustomizeConfig from './CustomizeConfig'
import IntervalSetting from './IntervalSetting'
import SwaggerPreview from './SwaggerPreview'

const INTERVAL_STORE_KEY = 'swagger-doc-preview_interval'

export default {
  name: 'App',
  components: {
    HistoryPanel,
    CustomizeConfig,
    IntervalSetting,
    SwaggerPreview
  },
  data () {
    const data = {
      loading: false,
      config: null,
      urlTyping: '',
      urlTypingError: '',
      url: '',
      r: new RegExp('^(?:[a-z]+:)?//', 'i'),
      interval: 1
    }

    if (INTERVAL_STORE_KEY in localStorage) {
      data.interval = parseInt(localStorage[INTERVAL_STORE_KEY])
    }

    return data
  },
  watch: {
    interval () {
      localStorage[INTERVAL_STORE_KEY] = this.interval
    }
  },
  async mounted () {
    this.config = this.$refs.customizeConfig.getConfig()
    if (this.$route.query.url) {
      this.urlTyping = this.$route.query.url
      this.url = this.$route.query.url
      this.onSubmit()
    }

    document.addEventListener('keyup', e => {
      // 浏览器中已经绑定有大量的 `CTRL` 键
      if (e.target == document.body && e.key.toLowerCase() === 'r') {
        this.refresh()
      }
    })
  },
  methods: {
    refresh () {
      this.$refs.swaggerPreview.reload()
    },
    onSubmit () {
      if (this.urlTyping && !this.r.test(this.urlTyping)) {
        this.urlTypingError = '需要输入完整的 URL'
      } else {
        this.urlTypingError = ''
        this.changeURL(this.urlTyping, true)
      }
    },
    async changeURL (url, pushState = false) {
      if (this.url === url) return

      this.url = url
      this.urlTyping = url
      this.$router.replace({ query: { url }})
      if (pushState) {
        await this.$refs.historyPanel.push(url)
      }
    },
    queryHistory (inputString, cb) {
      this.$refs.historyPanel.query(inputString).then(urls => cb(
        urls.map(url => {
          return { value: url }
        })
      ))
    }
  }
}
</script>

<style lang="scss" scoped>
.aside {
  min-height: 100vh;
  box-shadow: 0 2px 25px 3px #616161;
}

.header {
  display: flex;

  .header-center {
    flex: 1 0 auto;
    padding: 0 40px;
    .address-bar { width: 100%; }
  }

  .header-right {
    > * {
      margin-right: 5px;
    }

    line-height: 40px;
  }
}

.main {
  height: calc(100vh - 40px);
  overflow-y: auto;
}

@media (max-width: 1320px) {
  .aside {
    display: none;
  }
}
</style>

<style lang="scss">
body {
  margin: 0;
}
</style>
